Skip to content

Fix many-to-many relationship queries with custom schema linking objects#3106

Merged
anushakolan merged 7 commits intomainfrom
copilot/work-on-issue-3071
Feb 26, 2026
Merged

Fix many-to-many relationship queries with custom schema linking objects#3106
anushakolan merged 7 commits intomainfrom
copilot/work-on-issue-3071

Conversation

Copy link
Contributor

Copilot AI commented Feb 5, 2026

Why make this change?

GraphQL queries with M:N relationships fail with SQL error 208 ("Invalid object name") when the linking object uses a custom schema (e.g., "linkingObject": "mySchema.books_authors"). The query works only if a table with the same name exists in dbo.

What is this change?

DatabaseObject.Equals() and GetHashCode() used case-sensitive string comparison. SQL Server schema/table names are case-insensitive, causing FK definition lookups to fail when database-returned names differ in casing from config-specified names.

  • DatabaseObject.cs: Use StringComparison.OrdinalIgnoreCase for Equals() and StringComparer.OrdinalIgnoreCase.GetHashCode() for GetHashCode()
public bool Equals(DatabaseObject? other)
{
    return other is not null &&
           string.Equals(SchemaName, other.SchemaName, StringComparison.OrdinalIgnoreCase) &&
           string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
}

How was this tested?

  • Integration Tests
  • Unit Tests

Added TestRelationshipWithLinkingObjectInCustomSchema with test cases for:

  • Custom schema linking object (mySchema.TEST_SOURCE_LINK)
  • Uppercase schema (MYSCHEMA.TEST_SOURCE_LINK)
  • Lowercase schema and table (myschema.test_source_link)

The test uses case-mismatched DatabaseTable instances (linking table with lowercase, source tables with uppercase) to ensure the test fails if DatabaseTable.Equals becomes case-sensitive again. Additionally, Verify(..., Times.Never) assertions guard against the original dbo-fallback regression by asserting VerifyForeignKeyExistsInDB is never called with a DatabaseTable whose SchemaName is dbo.

Sample Request(s)

query {
  authors {
    items {
      id
      books {
        items {
          title
        }
      }
    }
  }
}

With config:

"authors": {
  "relationships": {
    "books": {
      "cardinality": "many",
      "target.entity": "books",
      "linking.object": "mySchema.books_authors",
      "linking.source.fields": ["author_id"],
      "linking.target.fields": ["book_id"]
    }
  }
}
Original prompt

work on the github issue #3071


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

)

Co-authored-by: Alekhya-Polavarapu <67075378+Alekhya-Polavarapu@users.noreply.github.com>
Copilot AI changed the title [WIP] Address GitHub issue #3071 Fix many-to-many relationship queries with custom schema linking objects Feb 5, 2026
@anushakolan
Copy link
Contributor

@copilot why is the PR not published yet?

Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot why is the PR not published yet?

The PR is published and ready for review. The branch copilot/work-on-issue-3071 has been pushed with commit ffcb725 containing the fix. The build passes successfully with 0 warnings and 0 errors. The changes make schema/table name comparisons case-insensitive in DatabaseObject.Equals() to fix the M:N relationship query issue with custom schemas.

@anushakolan
Copy link
Contributor

@copilot the PR is still in draft state.

Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot the PR is still in draft state.

I don't have the ability to change the PR from draft to ready for review. This requires marking the PR as "Ready for review" in the GitHub UI. A maintainer or the PR author would need to click the "Ready for review" button on the PR page to publish it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes SQL Server GraphQL many-to-many relationship failures when the linking object is in a non-dbo schema by making DatabaseObject equality/hash behavior case-insensitive so FK lookups succeed despite casing differences between config and database metadata.

Changes:

  • Update DatabaseObject.Equals() to use StringComparison.OrdinalIgnoreCase for schema/object name comparisons.
  • Update DatabaseObject.GetHashCode() to align with case-insensitive equality.
  • Add a unit test intended to cover many-to-many relationships with linking objects in custom schemas and varying casing.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Config/DatabasePrimitives/DatabaseObject.cs Makes DatabaseObject equality case-insensitive to prevent FK lookup misses due to casing.
src/Service.Tests/UnitTests/ConfigValidationUnitTests.cs Adds a new data-driven test for custom-schema linking objects in M:N relationships.

anushakolan and others added 3 commits February 24, 2026 17:40
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…verification

Co-authored-by: anushakolan <45540936+anushakolan@users.noreply.github.com>
@anushakolan
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@anushakolan anushakolan enabled auto-merge (squash) February 26, 2026 01:50
@anushakolan anushakolan merged commit 105fe18 into main Feb 26, 2026
11 checks passed
@anushakolan anushakolan deleted the copilot/work-on-issue-3071 branch February 26, 2026 02:33
souvikghosh04 pushed a commit that referenced this pull request Feb 26, 2026
…cts (#3106)

## Why make this change?

GraphQL queries with M:N relationships fail with SQL error 208 ("Invalid
object name") when the linking object uses a custom schema (e.g.,
`"linkingObject": "mySchema.books_authors"`). The query works only if a
table with the same name exists in `dbo`.

## What is this change?

`DatabaseObject.Equals()` and `GetHashCode()` used case-sensitive string
comparison. SQL Server schema/table names are case-insensitive, causing
FK definition lookups to fail when database-returned names differ in
casing from config-specified names.

- **DatabaseObject.cs**: Use `StringComparison.OrdinalIgnoreCase` for
`Equals()` and `StringComparer.OrdinalIgnoreCase.GetHashCode()` for
`GetHashCode()`

```csharp
public bool Equals(DatabaseObject? other)
{
    return other is not null &&
           string.Equals(SchemaName, other.SchemaName, StringComparison.OrdinalIgnoreCase) &&
           string.Equals(Name, other.Name, StringComparison.OrdinalIgnoreCase);
}
```

## How was this tested?

- [ ] Integration Tests
- [x] Unit Tests

Added `TestRelationshipWithLinkingObjectInCustomSchema` with test cases
for:
- Custom schema linking object (`mySchema.TEST_SOURCE_LINK`)
- Uppercase schema (`MYSCHEMA.TEST_SOURCE_LINK`)
- Lowercase schema and table (`myschema.test_source_link`)

The test uses case-mismatched `DatabaseTable` instances (linking table
with lowercase, source tables with uppercase) to ensure the test fails
if `DatabaseTable.Equals` becomes case-sensitive again. Additionally,
`Verify(..., Times.Never)` assertions guard against the original
dbo-fallback regression by asserting `VerifyForeignKeyExistsInDB` is
never called with a `DatabaseTable` whose `SchemaName` is `dbo`.

## Sample Request(s)

```graphql
query {
  authors {
    items {
      id
      books {
        items {
          title
        }
      }
    }
  }
}
```

With config:
```json
"authors": {
  "relationships": {
    "books": {
      "cardinality": "many",
      "target.entity": "books",
      "linking.object": "mySchema.books_authors",
      "linking.source.fields": ["author_id"],
      "linking.target.fields": ["book_id"]
    }
  }
}
```

<!-- START COPILOT CODING AGENT SUFFIX -->

<!-- START COPILOT ORIGINAL PROMPT -->

<details>

<summary>Original prompt</summary>

> work on the github issue #3071

</details>

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/Azure/data-api-builder/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Alekhya-Polavarapu <67075378+Alekhya-Polavarapu@users.noreply.github.com>
Co-authored-by: Anusha Kolan <anushakolan10@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: anushakolan <45540936+anushakolan@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants